#include<stdio.h>
#include <stdlib.h>
#include<string.h>
#include <unistd.h>
#include <sys/types.h>      
#include <sys/wait.h>
#include<errno.h>
#include <sys/stat.h>
#include <fcntl.h>
char arr[512];
char copyarr[512];
#define NUM 32
char* str[NUM];
#define SEP " "
#define None_Redir 0
#define In_Redir 1
#define Out_Redir 2
#define App_Redir 3
int redir_type=None_Redir;
int exitcode=0;
char *filename=NULL;
char*getname()
{
char *name=getenv("USER");
if(name==NULL)return NULL;
return name;
}
char*gethost()
{
char*hostname=getenv("HOSTNAME");
if(hostname==NULL)return NULL;
return hostname;
}
 char*gethome()                                                                                                  {
  char*home=getenv("HOME");
  if(home==NULL)return NULL;
     return home;
 }
char*getpwd()
{
char*pwd=getenv("PWD");
if(pwd==NULL)return NULL;
char*p=pwd+strlen(pwd)-1;
   while((*p)!='/')
   {
    
   p--;

   }
   return p;
}
void getcommandline()
{
 printf("[%s@%s %s]$",getname(),gethost(),strlen(getpwd())==1? "/" : getpwd()+1);
}
void getcommandstr()
{
fgets(arr,sizeof(arr),stdin);
arr[strlen(arr)-1]='\0';
memcpy(copyarr,arr,strlen(arr));
}
void splidcomandstr()
{
 
str[0]=strtok(arr,SEP);
int index=1;
while((str[index++]=strtok(NULL,SEP)));
}
void finishcommand()
{
int id=fork();
if(id==0)
{
if(filename!=NULL)
{
if(redir_type==App_Redir)
{
int fd=open(filename,O_WRONLY|O_CREAT|O_APPEND,0666);
dup2(fd,1);
}
else if(redir_type==Out_Redir)
{
int fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,0666);
  dup2(fd,1); 
}
else if(redir_type==In_Redir)
{

int fd=open(filename,O_RDONLY);
dup2(fd,0); 
}
else
{}
}
execvp(str[0],str);
exit(exitcode);
}
int status=0;
int ref=waitpid(id,&status,0);
if(ref>0)
{

exitcode=WEXITSTATUS(status);
if(exitcode!=0)printf("%s:%s:%d\n",str[0],strerror(exitcode),exitcode);
}

}
 void cd()
  {
   char* path=str[1];
   if(path==NULL)path=gethome();
    chdir(path);
    
 
   char cwd[1024];
    
    char temp[1024];
   getcwd(temp,sizeof(temp));
   
    snprintf(cwd,sizeof(cwd),"PWD=%s",temp);
    putenv(cwd);                                                                                                     
  }
int Built_incommands()                                                                                             
  { int yes=0;
  char* built=str[0];
  if(strcmp(built,"cd")==0)
  {
   yes=1;
   cd();
  }
  else if(strcmp(built,"echo")==0&&strcmp(str[1],"$?")==0)
  {
  yes=1;
 printf("%d\n",exitcode);
  exitcode=0;
  }
 
 return yes;
 
 }
void redirection()
{
int begin=0;
int end=strlen(copyarr);
while(begin<end)
{
  if(copyarr[begin]=='>')
  {
   if(copyarr[begin+1]=='>')
   {
    copyarr[begin++]=0;
    begin++;
    redir_type=App_Redir;
    while(copyarr[begin]==' ')
     {begin++;}
   filename=copyarr+begin;
   }
   else
   { copyarr[begin++]=0;
     redir_type=Out_Redir;
     while(copyarr[begin]==' ')                                                 
      {begin++;}
     filename=copyarr+begin;
   }

  }
  else if(copyarr[begin]=='<')
  {
    copyarr[begin++]=0;  
     redir_type=In_Redir;
       while(copyarr[begin]==' ')                                                 
       {begin++;}
      filename=copyarr+begin;



  }
  else 
  {
   begin++;




  }
  
}
memset(arr,'\0',512);
memcpy(arr,copyarr,strlen(copyarr));
}
int main()
{
   int quit=0;
  while(!quit)
  { filename=NULL;
    memset(copyarr,'\0',512);
    redir_type=None_Redir;
  getcommandline();
  getcommandstr();
  redirection(); 
  splidcomandstr();
  
 // printf("redir_type:%d\n",redir_type);
 // printf("filename:%s\n",filename);
  if(Built_incommands())
    continue;
  finishcommand();
  }
}
